﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BegInterfaces;
using BegEntities;
using BegMailServer;
using Database;

namespace Logic
{
    /// <summary>
    /// MailLogic innehåller metoder för att hämta och behandla data,
    /// den instansierar även en mailservern och en metod för att prenumerera
    /// på dess mailgotten händelse
    /// </summary>
    public class MailLogic : ILogik
    {
        private MailServer mailServer;
        private List<Email> tempMails;
        
        /// <summary>
        /// konstruktor utan parametrar
        /// </summary>
        public MailLogic()
        {
            mailServer = new MailServer(true); //instansierar ett mailserver objekt
            mailServer.MailGotten += new MailServer.MailEventHandler(mailGotten); //Kopplar händelsehanterare 
            mailServer.Start(); //startar mailservern
            tempMails = new List<Email>();
        }

        /// <summary>
        /// Metoden är en händelsehaterare, körs när mailservern avfyrar mailgotten event.
        /// Tar emot en dictionary med nyckel/värde par som används för att befolka ett nytt email.
        /// Sparar sedan objektet lokalt samt i databasen.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void mailGotten(Object sender, BegMailEventArgs e)
        {

            string pattern = @"\<(.*?)\>"; //reg.ex som används för att skilja på emailAdress

            string fromRaw = e.Mail["From"];
            string fromEmail = System.Text.RegularExpressions.Regex.Match(fromRaw, pattern).ToString();
            fromEmail = trimEmail(fromEmail);
            string fromName = System.Text.RegularExpressions.Regex.Replace(fromRaw, pattern, "");

            string toRaw = e.Mail["To"];
            string toEmail = System.Text.RegularExpressions.Regex.Match(toRaw, pattern).ToString();
            toEmail = trimEmail(toEmail);
            string toName = System.Text.RegularExpressions.Regex.Replace(toRaw, pattern, "");

            DateTime d = DateTime.Parse(e.Mail["Date"]);

            Email email = new Email(System.Guid.NewGuid(), d, new EmailAddress(fromEmail, fromName), false, e.Mail["Message"], MessageBox.Inbox, e.Mail["Subject"], new EmailAddress(toEmail, toName));

            XmlDatabase db = new XmlDatabase();
            db.AddMessage(email); //kallar på metod i databaslagret som skriver emailet till xml-fil
            tempMails.Add(email); //spara emailet lokalt

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        private string trimEmail(string s)
        {
            return s.Substring(1, s.Length - 2);
        }

        /// <summary>
        /// tar bort ett email
        /// </summary>
        /// <param name="msgID">ID:et för det email som ska tas bort</param>
        /// <returns>bool</returns>
        public bool DeleteMessage(Guid msgID)
        {
            XmlDatabase xml = new XmlDatabase();
            List<Email> emailList = new List<Email>();
            emailList = xml.GetMessages();
            bool success = false;

            foreach (Email e in emailList)
            {
                if (e.ID == msgID)
                {
                    success = xml.DeleteMessage(e);

                    break;
                }
            }
            return success;
        }

        /// <summary>
        /// Returnera den temporära listan med nyinkomna mail
        /// </summary>
        /// <returns></returns>
        public List<Email> GetNewMessages()
        {
            List<Email> returnTemp = tempMails;
            return returnTemp;
        }

        /// <summary>
        /// hämtar alla email med messagebox status inbox eller sent
        /// </summary>
        /// <param name="mbox">sent eller inbox</param>
        /// <returns>en lista med email var messagebox status överrensstämmer</returns>
        public List<Email> LoadMessages(MessageBox mbox)
        {
            XmlDatabase xml = new XmlDatabase();
            ClearTemp();
            return xml.GetMessages(mbox);
        }

        /// <summary>
        /// hämtar alla email från databasen genom att kalla
        /// </summary>
        /// <returns></returns>
        public List<Email> LoadMessages()
        {
            XmlDatabase xml = new XmlDatabase();
            ClearTemp();
            return xml.GetMessages();
        }

        /// <summary>
        /// skickar ett mail till mailservern
        /// </summary>
        /// <param name="message">ett email objekt</param>
        /// <returns>en bool om mailet tagits emot eller ej</returns>
        public bool SendMail(Email message)
        {

            Dictionary<string, string> list = new Dictionary<string, string>();
            list.Add("Date", message.Date.ToString());
            list.Add("From", message.From.ToString());
            list.Add("ID", message.ID.ToString());
            list.Add("IsRead", message.IsRead.ToString());
            list.Add("Message", message.Message);
            list.Add("MsgBox", message.MsgBox.ToString());
            list.Add("Subject", message.Subject);
            list.Add("To", message.To.ToString());

            if (mailServer.SendMail(list))
            {
                XmlDatabase xml = new XmlDatabase();
                if (xml.AddMessage(message))
                {
                    return true;
                }
                else
                {
                    return false;
                }
                
            }
            else
            {
                return false;
            }

        }

        /// <summary>
        /// rensar listan tempMails
        /// </summary>
        public void ClearTemp()
        {
            tempMails.Clear();
        }

        /// <summary>
        /// ToggleRead ändrar ett Email isRead status
        /// </summary>
        /// <param name="msgID">email:ets genererade ID</param>
        /// <param name="isRead">isRead är en bool, beroende på status ändrats </param>
        /// <returns></returns>
        public bool ToggleRead(Guid msgID, bool isRead)
        {
            XmlDatabase xml = new XmlDatabase();
            List<Email> emailList = new List<Email>();
            emailList = xml.GetMessages();
            bool success = false;

            foreach (Email e in emailList)
            {
                if (msgID == e.ID)
                {
                    if (isRead == true)
                    {
                        e.IsRead = false;
                    }
                    else
                    {
                        e.IsRead = true;
                    }
                    success = xml.ModifyMessage(e);
                }
            }
            return success;
        }

    }
}
